// se://extensions/

// IndexedDB 管理类（用于临时图片数据）
class IndexedDBManager {
  constructor() {
    this.dbName = 'multi-image-download'.toUpperCase();
    this.dbVersion = 2;
    this.imagesStoreName = 'images-Store'.toUpperCase();
    this.db = null;
    this.ready = this.initDB();
  }

  initDB() {
    return new Promise((resolve, reject) => {
      console.log('正在打开 IndexedDB, 版本:', this.dbVersion);
      const request = window.indexedDB.open(this.dbName, this.dbVersion);

      request.onerror = (event) => {
        console.error('Database error:', event.target.errorCode);
        reject(event.target.error);
      };

      request.onsuccess = (event) => {
        this.db = event.target.result;
        const storeNames = Array.from(this.db.objectStoreNames);
        console.log('IndexedDB 打开成功，当前版本:', this.db.version, '存储空间:', storeNames);
        resolve(this.db);
      };

      request.onupgradeneeded = (event) => {
        console.log('IndexedDB 升级中，从版本', event.oldVersion, '到', event.newVersion);
        this.db = event.target.result;

        // 创建图片存储空间
        if (!this.db.objectStoreNames.contains(this.imagesStoreName)) {
          const imagesStore = this.db.createObjectStore(this.imagesStoreName, { keyPath: 'id' });
          imagesStore.createIndex('id', 'id', { unique: false });
          console.log('✅ 已创建图片存储空间:', this.imagesStoreName);
        }
      };
    });
  }

  async ensureReady() {
    await this.ready;
  }

  async saveImages(images) {
    await this.ensureReady();
    const transaction = this.db.transaction([this.imagesStoreName], 'readwrite');
    const store = transaction.objectStore(this.imagesStoreName);

    // 清空对象存储中的所有数据
    await new Promise((resolve, reject) => {
      const clearRequest = store.clear();
      clearRequest.onsuccess = () => resolve();
      clearRequest.onerror = () => reject(clearRequest.error);
    });

    // 添加所有图片
    await Promise.all(
      images.map(data =>
        new Promise((resolve, reject) => {
          const request = store.add({ ...data });
          request.onsuccess = () => resolve();
          request.onerror = () => reject(request.error);
        })
      )
    );
  }

  async getImages() {
    await this.ensureReady();
    const transaction = this.db.transaction([this.imagesStoreName], 'readonly');
    const store = transaction.objectStore(this.imagesStoreName);
    const request = store.getAll();

    return new Promise((resolve, reject) => {
      request.onsuccess = (event) => resolve(event.target.result);
      request.onerror = () => reject(request.error);
    });
  }
}

// Chrome Storage 管理类（用于持久化配置，不会被清除缓存删除）
class ChromeStorageManager {
  async setConfig(key, value) {
    return new Promise((resolve, reject) => {
      chrome.storage.local.set({ [key]: value }, () => {
        if (chrome.runtime.lastError) {
          reject(chrome.runtime.lastError);
        } else {
          resolve();
        }
      });
    });
  }

  async getConfig(key, defaultValue = null) {
    return new Promise((resolve, reject) => {
      chrome.storage.local.get(key, (result) => {
        if (chrome.runtime.lastError) {
          reject(chrome.runtime.lastError);
        } else {
          resolve(result[key] !== undefined ? result[key] : defaultValue);
        }
      });
    });
  }
}

// 创建管理实例
const dbManager = new IndexedDBManager();
const storageManager = new ChromeStorageManager();
let currImages;

// 初始化 g_localIndex（存储在 chrome.storage.local，不会被清除缓存删除）
(async () => {
  try {
    console.log('开始初始化 g_localIndex...');
    const savedIndex = await storageManager.getConfig('g_localIndex');
    console.log('当前 g_localIndex 值:', savedIndex);
    if (savedIndex === null || savedIndex == '0') {
      const indexDef = '4091';
      await storageManager.setConfig('g_localIndex', indexDef);
      console.log('✅ 已初始化 g_localIndex =', indexDef, '(chrome.storage.local)');
    } else {
      console.log('✅ g_localIndex 已存在，值为:', savedIndex);
    }
  } catch (error) {
    console.error('❌ 初始化 g_localIndex 失败:', error);
  }
})();

function generateUniqueId() {
  return Date.now().toString(36) + Math.random().toString(36).substring(2);
}

// 是否漫画地址
function isComicHrefFn() {
  const href = window.location.href;
  return (
    href.includes('//5ikanhm.top') ||
    href.includes('//xiaoniao8.com') ||
    href.includes('//xiaoniao6.org')
  );
}

class LocalIndexManager {
  constructor(storageManager) {
    this.storageManager = storageManager;
    this.currentIndex = 0;
    this.initialized = false;
  }

  async init() {
    if (!this.initialized) {
      const savedIndex = await this.storageManager.getConfig('g_localIndex');
      // 如果 chrome.storage 中没有值，初始化为 4091 并保存
      if (savedIndex === null) {
        this.currentIndex = 4091;
        await this.storageManager.setConfig('g_localIndex', '4091');
      } else {
        this.currentIndex = Number(savedIndex);
      }
      this.initialized = true;
    }
  }

  async getIndex() {
    await this.init();
    this.currentIndex++;
    return this.currentIndex;
  }

  async saveIndex() {
    await this.storageManager.setConfig('g_localIndex', String(this.currentIndex));
  }

  // 确保最后保存
  async finalize() {
    await this.saveIndex();
  }
}

async function getImages(selectorName, indexManager) {
  const str = selectorName || 'img';
  const selectorArr = str.split('@');
  let nodeList = [];
  for (let index = 0; index < selectorArr.length; index++) {
    nodeList = document.querySelectorAll(selectorArr[index]);
    if (nodeList.length) break;
  }
  if (!nodeList.length) return [];

  const images = [];
  const isComicHref = isComicHrefFn();
  let baseIndex = 0;
  if (!isComicHref) {
    baseIndex = await indexManager.getIndex(); // 只调用一次获取起始索引
  }

  const promises = Array.from(nodeList).map((img, arrayIndex) => {
    return new Promise(resolve => {
      setTimeout(() => {
        const { alt, naturalWidth, naturalHeight } = img;
        const pageTitle = processTitle(document.title);
        const src = img.getAttribute('data-original') || img.getAttribute('data-src') || img.src;
        const finalIndex = isComicHref ? arrayIndex + 1 : baseIndex + arrayIndex;
        const fileName = `${finalIndex}.jpg`;

        const data = {
          id: generateUniqueId(),
          index: finalIndex,
          width: naturalWidth,
          height: naturalHeight,
          area: naturalWidth * naturalHeight,
          alt,
          src,
          pageTitle,
          fileName,
        };
        images.push(data);
        resolve();
      }, arrayIndex * 300);
    });
  });

  await Promise.all(promises);
  // 更新索引管理器（需要在await之后，因为images.length需要等待promises完成）
  if (!isComicHref && images.length > 0) {
    indexManager.currentIndex = baseIndex + images.length - 1;
  }
  currImages = images;
  return images;
}

chrome.runtime.onMessage.addListener(async function(message, sender, sendResponse) {
  console.log('页面端接收消息 ==', message.action);
  if (message.action === 'collectImages') {
    const indexManager = new LocalIndexManager(storageManager);
    const images = await getImages(message.selectorName, indexManager);
    if (images.length) {
      await dbManager.saveImages(images);
    }
    chrome.runtime.sendMessage({
      action: 'savedImages',
      message: images.length ? '图片保存成功' : '未获取到图片',
      length: images.length,
    });
  } else if (message.action === 'db_getImages') {
    const images = await dbManager.getImages();
    chrome.runtime.sendMessage({ action: 'sendImages', images });
  } else if (message.action === 'dl_getImages') {
    const indexManager = new LocalIndexManager(storageManager);
    const images = await getImages(message.selectorName, indexManager);
    chrome.runtime.sendMessage({ action: 'sendImages', images });
  } else if (message.action === 'dl_currPage') {
    if (currImages?.length) {
      const imageUrls = currImages.map(item => item.src);
      alert(`正在执行下载图片，图片地址：${JSON.stringify(imageUrls)}`);
      chrome.runtime.sendMessage({
        action: 'dl_background',
        urls: imageUrls,
        fileName: document.title,
      });
    }
  }
});

function processTitle(data) {
  // 使用正则表达式匹配所有非英文字母（a-zA-Z）、非汉字（\u4e00-\u9fa5）和非数字（0-9）的字符，并将其替换为空字符串
  return data.replace(/[^\w\u4e00-\u9fa5]/g, '').replace(/_|今日头条|抖音/g, '').trim();
}

async function downloadImage(url, fileName) {
  try {
    const response = await fetch(url);
    const blob = await response.blob();
    const blobUrl = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.style.display = 'none';
    link.href = blobUrl;
    link.download = fileName;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(blobUrl);
    await new Promise(resolve => setTimeout(resolve, 1000));
    return true;
  } catch (error) {
    console.error('Download failed:', error);
    return false;
  }
}

// 取消收藏
async function cacelCollectFn() {
  const btn = document.querySelector('.detail-interaction-collect');
  if (btn?.classList.contains('collected')) {
    btn.click();
    await new Promise(resolve => setTimeout(resolve, 500));
  }
}

setTimeout(async () => {
  const indexManager = new LocalIndexManager(storageManager);
  const images = await getImages('.weitoutiao-img@.syl-page-img@.comicpage img@.lazyload@.comicpage .cropped', indexManager);

  if (images.length) {
    if (window.location.href.includes('www.toutiao.com')) {
      await indexManager.finalize();
    } else {
      alert(`图片个数为 ${images.length}`);
    }
    for (const image of images) {
      await downloadImage(image.src, image.fileName);
    }
    await cacelCollectFn();
    chrome.runtime.sendMessage({ action: 'closeTabAfterDownload' });
    return;
  }

  // 处理视频下载
  let videoNode = document.querySelector('.video-slider-wrapper video');
  if (videoNode) {
    const title = processTitle(document.title) + '.mp4';
    await downloadImage(videoNode.src, title);
    chrome.runtime.sendMessage({ action: 'closeTabAfterDownload' });
    return;
  }

  videoNode = document.querySelector('.xg-video-container video');
  if (videoNode) {
    const title = processTitle(document.title) + '.mp4';
    if (videoNode.src) {
      await downloadImage(videoNode.src, title);
      chrome.runtime.sendMessage({ action: 'closeTabAfterDownload' });
    } else {
      const nodes = Array.from(videoNode.querySelectorAll('source'));
      for (const ele of nodes) {
        const res = await downloadImage(ele.src, title);
        if (res) {
          chrome.runtime.sendMessage({ action: 'closeTabAfterDownload' });
          break;
        }
      }
    }
  }
}, 1000);
